package com.hullbreach.rogue;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.andengine.util.debug.Debug;

public class Scheduler{

	private LinkedList<GameObject> queue = new LinkedList<GameObject>();
	private GameObject currentActor;
	private boolean currentActorRemoved;
	private int lockCount;
	public boolean playersTurn = false;
	
    public Scheduler()
    {
    	queue = new LinkedList<GameObject>();
    	currentActor = null;
    	currentActorRemoved = false;
    	lockCount = 0;
    }

    
    /**
     * Lock the scheduler so no further actions will be processed until unlocked.
     *
     * Lock is recursive, meaning that this method can be called multiple
     * times and to resume processing, unlock should be called that number of times.
     **/
 
    
    public void lock()
    {
        lockCount++;
    }    
    
 
    
    public void unlock()
    {
        if (lockCount == 0)
        {
        	Debug.e("Cannot unlock locked scheduler");
        }
        lockCount--;
    }    
    
    
    public GameObject addActor(GameObject actor)
    {
        queue.add(actor);
        return actor;
    }

    public void removeActor(GameObject actor)
    {
        queue.remove(actor);
        
        if (currentActor == actor)
        {
            currentActorRemoved = true;
        }
    }
	
    
    /**
     * Process one actor. Does nothing if locked.
     *
     * @return true if actor was processed successfully and we're ready to move on to the next one,
     * false if we're locked, there's no actors left or the current action wasn't processed
     * in this tick (async input, for example)
     **/    
    public boolean tick()
    {
        if (lockCount > 0)
        {
        	return false; 
        }
    	
    	//Debug.e("Number of actors" + queue.size());
    	GameObject actor = queue.getFirst();
        if (actor == null)
        {
            return false;
        }
 
        if (actor instanceof Player)
        {
        	this.lock();
        	this.playersTurn = true;
        	Debug.e("Player's Turn");
        }
        else
        {
        	Debug.e(actor.getClass().getName() + "'s turn");
        }
        
        //Debug.e("Actor Energy:" + actor.energy);
        while (actor.energy > 0)
        {
            currentActor = actor;
            Debug.e("Starting Act");
            int actionCost = actor.act();
            currentActor = null;

            if (currentActorRemoved)
            {
                currentActorRemoved = false;
                return true;
            }
        	
            if (actionCost < 0)
            {
                return false;
            }
            
            actor.energy -= actionCost;
            Debug.e( actor.getClass().getName() + " took turn and finished with "+actor.energy );
            
            if (lockCount > 0)
            {
            	return false; 
            }
        }

        actor.energy += actor.speed;
        queue.addLast(queue.removeFirst());
        
        return true;
    }
    
}